package drawCard

import (
	"encoding/json"
	"math/rand"
	"sanguo/node/common/DropPool"
	table_DrawCard "sanguo/node/table/excel/table/DrawCard"
	cs_msg "sanguo/protocol/cs/message"

	"github.com/golang/protobuf/proto"
)

type DrawCard struct {
	DrawCardType      int32 //抽卡类型
	DrawCardTimes     int32
	DrawCardLoopTimes int32
	//NextFreeTime      int64 //下一次免费时间
}

type RoleDrawCard struct {
	drawCards map[int32]*DrawCard
	dirty     map[int32]bool
	dbDirty   bool
}

func FuncNewDrawCard() map[int32]*DrawCard {
	ret := map[int32]*DrawCard{}
	for _, v := range table_DrawCard.Table_.IDMap {
		ret[v.ID] = newDrawCard(v.ID)
	}
	return ret
}

func newDrawCard(typeID int32) *DrawCard {
	DCDef := table_DrawCard.Table_.IDMap[typeID]
	//now := time.Now().Unix()
	ret := &DrawCard{
		DrawCardType:      DCDef.ID,
		DrawCardTimes:     0,
		DrawCardLoopTimes: 0,
		//NextFreeTime:      now,
	}
	return ret
}

/*
func (this *DrawCard) SetNextFreeTime() {
	DCDef := table_DrawCard.Table_.IDMap[this.DrawCardType]
	now := time.Now().Unix()
	this.NextFreeTime = now + int64(DCDef.FreeTime)*60*60
}

func (this *DrawCard) CheckFreeTime() bool {
	now := time.Now().Unix()
	if now < this.NextFreeTime {
		return false
	}
	return true
}
*/

func (this *RoleDrawCard) GetDrawCard(typeID int32) *DrawCard {
	return this.drawCards[typeID]
}

func (this *RoleDrawCard) PlayerDrawCard(typeID, times int32) map[int32]*DropPool.Award {
	DCDef := table_DrawCard.Table_.IDMap[typeID]
	drawCard := this.GetDrawCard(typeID)

	awards := map[int32]*DropPool.Award{}

	for i := int32(0); i < times; i++ {
		drawCard.DrawCardLoopTimes++
		drawCard.DrawCardTimes++

		if DCDef.DrawCardTimes == drawCard.DrawCardTimes && DCDef.DrawCardTimes != 0 {
			awards[i] = AppointDrop(typeID)
			if drawCard.DrawCardLoopTimes == DCDef.DrawCardLoopTimes && DCDef.DrawCardLoopTimes != 0 {
				drawCard.DrawCardLoopTimes = 0
			}
		} else if drawCard.DrawCardLoopTimes == DCDef.DrawCardLoopTimes && DCDef.DrawCardLoopTimes != 0 {
			awards[i] = LoopDrop(typeID)
			drawCard.DrawCardLoopTimes = 0
		} else {
			awards[i] = RandDrop(typeID)
		}

	}

	/*
		if drawCard.CheckFreeTime() {
			drawCard.SetNextFreeTime()
		}
	*/

	this.dirty[typeID] = true
	this.SetDirtyFlag()
	return awards
}

//在指定次数掉落
func AppointDrop(typeID int32) *DropPool.Award {
	dropPoolID := table_DrawCard.Table_.IDMap[typeID].DropPoolID
	return DropPool.InitAward(dropPoolID)
}

//循环掉落指定库
func LoopDrop(typeID int32) *DropPool.Award {
	dropPoolID := table_DrawCard.Table_.IDMap[typeID].DropPoolIDLoop
	return DropPool.InitAward(dropPoolID)
}

func RandDrop(typeID int32) *DropPool.Award {
	DCDef := table_DrawCard.Table_.IDMap[typeID]

	var dropPoolID int32 = 0 //掉落库ID
	p := rand.Int31n(10000) + 1
	var pp_ int32 = 0 //读表的概率累加值
	for _, v := range DCDef.DropPools {
		pp_ += v.DropChances
		if p <= pp_ {
			dropPoolID = v.DropPoolID
			break
		}
	}

	return DropPool.InitAward(dropPoolID)
}

func (this *RoleDrawCard) PackAllDrawCard() []*cs_msg.DrawCard {
	drawCards := []*cs_msg.DrawCard{}
	for _, v := range this.drawCards {
		drawCard := &cs_msg.DrawCard{
			DrawCardType:      proto.Int32(v.DrawCardType),
			DrawCardLoopTimes: proto.Int32(v.DrawCardLoopTimes),
			//NextFreeTime:      proto.Int64(v.NextFreeTime),
		}
		drawCards = append(drawCards, drawCard)
	}
	return drawCards
}

func (this *RoleDrawCard) GetDirtyLength() int {
	return len(this.dirty)
}

func (this *RoleDrawCard) PackModify() []*cs_msg.DrawCard {
	drawCards := []*cs_msg.DrawCard{}
	for id, b := range this.dirty {
		if b {
			delete(this.dirty, id)
			v := this.drawCards[id]
			drawCard := &cs_msg.DrawCard{
				DrawCardType:      proto.Int32(v.DrawCardType),
				DrawCardLoopTimes: proto.Int32(v.DrawCardLoopTimes),
				//NextFreeTime:      proto.Int64(v.NextFreeTime),
			}
			drawCards = append(drawCards, drawCard)
		}
	}
	return drawCards
}

/****************************************/

func (this *RoleDrawCard) PackJson(fields map[string]interface{}) {
	if this.dbDirty {
		jsonStr, err := json.Marshal(this.drawCards)
		if nil == err {
			fields["drawCard"] = jsonStr
		}
	}
}

func (this *RoleDrawCard) IsDirty() bool {
	return this.dbDirty
}

func (this *RoleDrawCard) SetDirtyFlag() {
	this.dbDirty = true
}

func (this *RoleDrawCard) ClearDirtyFlag() {
	this.dbDirty = false
}

func (this *RoleDrawCard) Init(drawCards map[int32]*DrawCard) {
	this.drawCards = drawCards
	this.dirty = map[int32]bool{}
	this.dbDirty = false
}
